home *** CD-ROM | disk | FTP | other *** search
- /*LINTLIBRARY*/
-
- /* @(#)makemove.c 1.15 91/11/13
- *
- * Interface to best computer strategy routines used by Reve.
- *
- * Copyright (C) 1990, 1991 - Rich Burridge & Yves Gallot.
- * All rights reserved.
- *
- * Permission is granted to copy this source, for redistribution
- * in source form only, provided the news headers in "substantially
- * unaltered format" are retained, the introductory messages are not
- * removed, and no monies are exchanged.
- *
- * Permission is also granted to copy this source, without the
- * news headers, for the purposes of making an executable copy by
- * means of compilation, provided that such copy will not be used
- * for the purposes of competition in any othello tournaments, without
- * prior permission from the authors.
- *
- * No responsibility is taken for any errors on inaccuracies inherent
- * either to the comments or the code of this program, but if reported
- * (see README file), then an attempt will be made to fix them.
- */
-
- #include "reve.h"
- #include "color.h"
- #include <unistd.h>
- #include <signal.h>
- #include "extern.h"
-
-
- void
- display_time(player, timeleft) /* Display time left in mm:ss format. */
- int player, timeleft ;
- {
- enum panel_type ptype ;
- int mins, secs ;
-
- mins = timeleft / 60 ;
- secs = timeleft % 60 ;
- ptype = (player == BLACK) ? BLACK_CLOCK : WHITE_CLOCK ;
- SPRINTF(items[(int) ptype].text, "%1d:%02d", mins, secs) ;
- if (DO_CLOCK) draw_clock(W_PANEL, ptype, DO_CLOCK) ;
- }
-
-
- void
- domove(pos, mv, nextpos, player)
- BOARD *pos, *nextpos ;
- int mv, player ;
- {
- register int i ;
- if (pos != nextpos) FOR_BOARD(i) nextpos->square[i] = pos->square[i] ;
-
- s_move = mv ;
- s_row = mv >> 3 ;
- s_col = mv & 7 ;
- s_player = player ;
- s_opponent = -player ;
- s_flip = TRUE ;
- s_pos = nextpos ;
-
- nextpos->square[s_move] = player ;
-
- (void) sandwich(-9) ;
- (void) sandwich(-8) ;
- (void) sandwich(-7) ;
- (void) sandwich(-1) ;
- (void) sandwich(1) ;
- (void) sandwich(7) ;
- (void) sandwich(8) ;
- (void) sandwich(9) ;
-
- nextpos->moves_left = (pos->moves_left) - 1 ;
- }
-
-
- FILE *
- find_file(filename)
- char *filename ;
- {
- char name[MAXLINE], *paths, *ptr ;
- int i = 0 ;
- FILE *fp = NULL ;
-
- if ((fp = fopen(filename, "r")) == NULL)
- {
- paths = getenv("PATH") ;
- if ((ptr = paths) && filename[0] != '/')
- for (;;)
- if (*ptr == ':' || *ptr == 0)
- {
- if (*ptr == 0) break ;
- name[i++] = '/' ;
- name[i] = 0 ;
- STRCAT(name, edgefile) ;
- if ((fp = fopen(name, "r")) != NULL) break ;
- if (*ptr == '\0') break ;
- ptr++ ;
- i = 0 ;
- }
- else name[i++] = *ptr++ ;
- }
- return(fp) ;
- }
-
-
- int
- fork_child()
- {
- char *argv[6] ; /* Reve_proc command line arguments. */
- int i, tabsiz ;
-
- PIPE(pipe_io[0]) ; /* Setup input pipe. */
- PIPE(pipe_io[1]) ; /* Setup output pipe. */
- switch (pid = fork())
- {
- case -1 : CLOSE(pipe_io[0][0]) ;
- CLOSE(pipe_io[0][1]) ;
- CLOSE(pipe_io[1][0]) ;
- CLOSE(pipe_io[1][1]) ;
- perror("reve fork failed") ;
- exit(1) ;
- case 0 : DUP2(pipe_io[0][0], 0) ; /* Child. */
- DUP2(pipe_io[1][1], 1) ;
- DUP2(pipe_io[1][1], 2) ;
-
- #ifdef NOGETDTAB
- #ifdef hpux
- tabsiz = _NFILE ;
- #else
- tabsiz = sysconf(_SC_OPEN_MAX) ;
- #endif /*hpux*/
- #else
- tabsiz = getdtablesize() ;
- #endif /*NOGETDTAB*/
-
- for (i = tabsiz; i > 2; i--) CLOSE(i) ;
- for (i = 0; i < NSIG; i++) SIGNAL(i, SIG_DFL) ;
- i = 0 ;
- argv[i++] = "reve_proc" ;
- argv[i++] = "-e" ;
- argv[i++] = edgefile ;
- if (saveres == TRUE) argv[i++] = "-log" ;
- if (debug == TRUE) argv[i++] = "-debug" ;
- argv[i] = (char *) NULL ;
- execvp(reveproc, argv) ;
- perror("reve child exec") ;
- _exit(-1) ;
- default : CLOSE(pipe_io[0][0]) ; /* Parent. */
- CLOSE(pipe_io[1][1]) ;
- }
- return(pid) ;
- }
-
-
- void
- init_clocks() /* Setup timer clocks. */
- {
- items[(int) BLACK_CLOCK].value = timevals[level] * 60 ;
- items[(int) WHITE_CLOCK].value = timevals[level] * 60 ;
- SPRINTF(items[(int) BLACK_CLOCK].text, "%1d:00", timevals[level]) ;
- SPRINTF(items[(int) WHITE_CLOCK].text, "%1d:00", timevals[level]) ;
- }
-
-
- int
- legal(mv, player, pos)
- BOARD *pos ;
- int mv, player ;
- {
- if (pos->square[mv]) return(FALSE) ; /* Already occupied */
-
- s_move = mv ;
- s_row = mv >> 3 ;
- s_col = mv & 7 ;
- s_player = player ;
- s_opponent = -player ;
- s_flip = FALSE ;
- s_pos = pos ;
-
- return(sandwich(-9) + sandwich(-8) + sandwich(-7) + sandwich(-1) +
- sandwich(1) + sandwich(7) + sandwich(8) + sandwich(9)) ;
- }
-
-
- void
- read_from_reve(fd)
- int fd ;
- {
- struct reve_out out ;
- int reply, sout ;
-
- if (!started) return ;
- sout = sizeof(struct reve_out) ;
- if ((reply = read(fd, (char *) &out, sout)) > 0)
- {
- profmax = out.depth ;
- if (out.type == M_BEST) show_best(out.move, out.note) ;
- else if (out.type == M_MOVE)
- {
- set_cursor(CANVASCUR) ;
- move = out.move ;
- note = out.note ;
- opponent_move(next_player) ;
- }
- else if (out.type == M_SUGGESTION)
- {
- if (legal(out.move, next_player, &board) == 0)
- FOR_BOARD(out.move)
- if (board.square[out.move] == FREE &&
- legal(out.move, next_player, &board)) break ;
- do_suggest(next_player, out.move, out.note, IS_ON) ;
- if (restore_moves) show_all(IS_ON) ;
- sstate = IS_ON ;
- suggestion = out.move ;
- snote = out.note ;
- processing = FALSE ;
- }
- }
- else
- {
- FPRINTF(stderr, "Couldn't get connection to reve_proc. Exiting.\n",
- progname) ;
- destroy_reve() ;
- }
- }
-
-
- void
- reset_clock(player)
- int player ;
- {
- time_t tval ;
-
- start_time = tval = time((time_t *) 0) ; /* Get local time from kernel. */
- if (player == BLACK) last_btime = tval ;
- else last_wtime = tval ;
- }
-
-
- void
- reset_time(timeleft)
- time_t timeleft ;
- {
- struct reve_in in ;
-
- in.type = M_TIME ;
- in.timeleft = timeleft ;
- WRITE(pipe_io[0][1], (char *) &in, sizeof(struct reve_in)) ;
- }
-
-
- /* Test whether the square move sandwiches a line
- * of enemy pieces in the direction [row_inc, col_inc];
- * If (s_flip) then update position by capturing such pieces
- * Returns the number of pieces captured.
- */
-
- int
- sandwich(increment)
- register int increment ;
- {
- register int square, offset ;
- int row_offset, col_offset, piece, piece_count ;
- int pcount = 0 ;
-
- if ((s_move+increment) < 0 || (s_move+increment) > 63) return(pcount) ;
- if (s_pos->square[s_move+increment] != s_opponent) return(pcount) ;
-
- /* Quick test to catch most failures -
- * note that the tested square may not even
- * be on the board, but the condition is a
- * sufficient one for failure.
- */
-
- row_offset = (increment < -1 ? s_row : /* inc -1: -9, -8, -7 */
- increment > 1 ? 7-s_row : 8) ; /* inc 1: 7, 8, 9 */
- col_offset = (increment & 4 ? s_col : /* inc -1: -9, -1, 7 */
- increment & 1 ? 7-s_col : 8) ; /* inc 1: -7, 1, 9 */
-
- offset = (row_offset > col_offset ? col_offset : row_offset) ;
-
- /* offset = shortest distance to an edge in the direction of search */
-
- if (2 > offset) return(pcount) ;
-
- piece_count = 1 ;
- square = s_move+increment ;
-
- while (--offset)
- {
- if (!(piece = s_pos->square[square += increment]))
- return(pcount) ; /* If empty square, give up */
-
- if (piece == s_player) break ;
- else piece_count++ ; /* Count opponent's pieces encountered */
- }
-
- if (!offset) return(pcount) ;
-
- pcount = piece_count ;
- if (s_flip)
- while (piece_count--)
- s_pos->square[square -= increment] = s_player ;
-
- return(pcount) ;
- }
-
-
- void
- update_clock(player, doinc) /* Decrement the clock for the current user. */
- int player, doinc ;
- {
- char str[MAXLINE] ;
- int diff, n, timeleft ;
- time_t cur_time, last_time ;
-
- diff = 0 ;
- cur_time = time((time_t *) 0) ;
- last_time = (player == BLACK) ? last_btime : last_wtime ;
- if (cur_time != last_time) diff = (int) (cur_time - last_time) ;
- if (doinc && diff <= 0) diff = 1 ;
- else if (diff <= 0) return ;
- if (player == BLACK)
- {
- last_btime = cur_time ;
- n = (int) BLACK_CLOCK ;
- }
- else
- {
- last_wtime = cur_time ;
- n = (int) WHITE_CLOCK ;
- }
- items[n].value -= diff ;
- if (items[n].value < 0) items[n].value = 0 ;
- display_time(player, items[n].value) ;
- if (DO_CLOCK && items[n].value == 0)
- {
- cmode = GAME_OVER ;
- SPRINTF(str, "Timer expired for %s. ***GAME OVER***",
- (player == BLACK) ? bstone_name : wstone_name) ;
- message(PANEL_MES, str) ;
- beep() ;
- }
- }
-
-
- int
- valid_move(board, player) /* Check if valid move for this player. */
- BOARD *board ;
- int player ;
- {
- int mv ;
- int valid ; /* Set if there is a valid move. */
-
- for (mv = 0; mv < 64; mv++)
- if (board->square[mv] == FREE)
- {
- valid = legal(mv, player, board) ;
- if (valid > 0) return(TRUE) ;
- }
- return(FALSE) ;
- }
-
-
- /*ARGSUSED*/
- void
- write_to_reve(mtype, reve_board, player, level)
- enum move_type mtype ;
- int *reve_board, player, level ;
- {
- int i ;
- struct reve_in in ;
-
- for (i = 0; i < 64; i++) in.board[i] = reve_board[i] ;
- in.player = player ;
- in.level = level ;
- in.type = mtype ;
- processing = TRUE ;
- WRITE(pipe_io[0][1], (char *) &in, sizeof(struct reve_in)) ;
- }
-